from microbit import *

cmd = [
    [0xAE],  # SSD1306_DISPLAYOFF
    [0xA4],  # SSD1306_DISPLAYALLON_RESUME
    [0xD5, 0xF0],  # SSD1306_SETDISPLAYCLOCKDIV
    [0xA8, 0x3F],  # SSD1306_SETMULTIPLEX
    [0xD3, 0x03],  # SSD1306_SETDISPLAYOFFSET
    [0 | 0x0],  # line #SSD1306_SETSTARTLINE
    [0x8D, 0x14],  # SSD1306_CHARGEPUMP
    [0x20, 0x00],  # SSD1306_MEMORYMODE
    [0x21, 0, 127],  # SSD1306_COLUMNADDR
    [0x22, 0, 63],  # SSD1306_PAGEADDR
    [0xA0 | 0x1],  # SSD1306_SEGREMAP
    [0xC8],  # SSD1306_COMSCANDEC
    [0xDA, 0x12],  # SSD1306_SETCOMPINS
    [0x81, 0xCF],  # SSD1306_SETCONTRAST
    [0xD9, 0xF1],  # SSD1306_SETPRECHARGE
    [0xDB, 0x40],  # SSD1306_SETVCOMDETECT
    [0xA6],  # SSD1306_NORMALDISPLAY
    [0xD6, 0],  # zoom set_power_off
    [0xAF],  # SSD1306_DISPLAYON
]

ADDR = 0x3C
screen = bytearray(1025)  # send byte plus pixels
screen[0] = 0x40


class OLED(object):
    """基本描述

    OLED1306显示屏

    """

    def __init__(self):
        for c in cmd:
            self.__command(c)

        # clear first
        self.set_clear()
        self.__set_zoom(1)
        self.il = 0
        self.last = ''

    def __command(self, c):
        i2c.write(ADDR, b"\x00" + bytearray(c))

    def __set_zoom(self, zoom=1):
        self.__command([0xD6, zoom])

    def __set_pos(self, col=0, page=0):
        self.__command([0xB0 | page])  # page number
        # take upper and lower value of col * 2
        c = col
        c1, c2 = c & 0x0F, c >> 4
        self.__command([0x00 | c1])  # lower start column address
        self.__command([0x10 | c2])  # upper start column address

    def set_clear(self):
        """

        删除所有显示信息，清屏

        """
        global screen
        for i in range(1, 1025):
            screen[i] = 0
        self.set_refresh()

    def set_refresh(self):
        """

        刷新显示

        """
        self.__set_pos()
        i2c.write(ADDR, screen)

    def set_text(self, x, y, s):
        """

        显示一行文本,一行最多24个字符，每个字符 10 * 5 PX， 通过zoom放大成10 * 10
        中间间隔

        Args:
            x (number): 第几个字符, 0 - 24
            y (number): Y 轴坐标 0 - 7
            s (str): 只接受字符串或字符类型参数,

        Returns:
            NONE
        """
        ind = 0
        text_x_px = 10
        str_len = len(s)
        for i in range(0, str_len):
            ch = Image(s[i])
            # print(ch, i, x)
            for c in range(0, text_x_px):
                col = 0
                ci = int(c / 2)
                for r in range(1, 6):  # microbit 像素点从0-5
                    p = ch.get_pixel(ci, r - 1)  # 获取点阵字符的像素点
                    col = col | (1 << r) if (p != 0) else col
                ind = int((x + i) * text_x_px + y * 128 + c)
                screen[ind] = col
                screen[ind + 1] = col
        left = int(x * text_x_px)
        top = int(y)
        self.__set_pos(left, top)
        ind0 = int(x * text_x_px + y * 128)
        i2c.write(ADDR, b"\x40" + screen[ind0: ind + 1])

    def set_number_center(self, text):
        [i, f] = text.split('.')

        int_length = len(i)

        if int_length < self.il:
            self.set_clear()

        self.il = int_length

        # 小数部分最多三位
        max_f = 3

        if len(f) < max_f:
            pad = max_f - len(f)
            for item in range(0, pad):
                f += '0'
        else:
            f = f[0:max_f]

        left = (120 - (len(i) + len(f)) * 10) / 2 / 10
        top = 2
        value = i + '.' + f
        self.set_text(left, top, value)

    def set_text_center(self, text):
        left = (130 - len(text) * 10) / 2 / 10
        top = 2
        self.set_text(left, top, text)

    def set_center(self, text):
        line = str(text)

        if '?' in self.last:
            self.set_clear()

        self.last = line
        if '.' in line:
            self.set_number_center(line)
            return

        self.set_clear()
        self.set_text_center(line)


if __name__ == "__main__":
    pm = OLED()
    a = 0
    pm.set_center("Ready?")
    while True:
        # 按下a键开始计时，获取系统运行时间作为起点时间
        if button_a.was_pressed():
            a = running_time()

        # 实时显示当前时间与起点时间的差值
        if a > 0:
            b = running_time()
            sj = (b - a) / 1000
            pm.set_center(sj)

        # 按下b键结束计时，保持两秒钟后重置起点时间为0
        if button_b.was_pressed():
            b = running_time()
            sj = (b - a) / 1000
            pm.set_center(sj)
            sleep(2000)
            a = 0
            pm.set_center("Ready?")
